package com.chat.websocket.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chat.websocket.entity.dto.MessageContentDTO;
import com.chat.websocket.entity.dto.SendMessageDTO;
import com.chat.websocket.entity.enums.MessageReadStatus;
import com.chat.websocket.entity.enums.ReadStatus;
import com.chat.websocket.entity.module.Friend;
import com.chat.websocket.entity.module.Message;
import com.chat.websocket.entity.vo.MessageContentVO;
import com.chat.websocket.mapper.FriendMapper;
import com.chat.websocket.mapper.MessageMapper;
import com.chat.websocket.service.MessageService;
import com.chat.websocket.util.websocket.WebSocket;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * SunJingxuan
 * 2022 \ 08 \ 10
 */
@Service
public class MessageServiceImpl implements MessageService {

	@Resource
	private MessageMapper messageMapper;

	@Resource
	private FriendMapper friendMapper;

	@Resource
	private WebSocket webSocket;

	@Override
	public Boolean
	sendMessageToUser(SendMessageDTO sendMessageDTO) throws IOException {
		Date now = new Date();
		Message message = new Message(sendMessageDTO.getSendUserId(), sendMessageDTO.getReceiveUserId(), sendMessageDTO.getSendMessageContent(), now, now);
		int insert = messageMapper.insert(message);
		if (insert > 0) {
			List<Integer> userIds = Arrays.asList(sendMessageDTO.getSendUserId(), sendMessageDTO.getReceiveUserId());
			LambdaUpdateWrapper<Friend> updateWrapper = new LambdaUpdateWrapper<>();
			updateWrapper.set(Friend::getChatListDeleteStatus, 0)
					.in(Friend::getUserId, userIds)
					.in(Friend::getFriendUserId, userIds);
			friendMapper.update(null, updateWrapper);
			return webSocket.onMessageToUser(sendMessageDTO.getSendUserId(), sendMessageDTO.getReceiveUserId(), sendMessageDTO.getSendMessageContent(), message.getId());
		}
		return false;
	}

	@Override
	public List<MessageContentVO> getHistoryMessage(MessageContentDTO messageContentDTO) {
		List<MessageContentVO> historyMessage = messageMapper.getHistoryMessage(messageContentDTO);
		Collections.reverse(historyMessage);
		LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(Message::getSendUserId, messageContentDTO.getReceiveUserId()).eq(Message::getReceiveUserId, messageContentDTO.getSendUserId()).eq(Message::getReadStatus, ReadStatus.UNREAD.getStatus());
		Long count = messageMapper.selectCount(queryWrapper);
		if (count > 0) {
			LambdaUpdateWrapper<Message> updateWrapper = new LambdaUpdateWrapper<>();
			List<Message> messages = messageMapper.selectList(queryWrapper);
			if (!CollectionUtils.isEmpty(messages)) {
				updateWrapper.set(Message::getReadStatus, MessageReadStatus.HAVE_READ.getStatus()).in(Message::getId, messages.stream().map(Message::getId).collect(Collectors.toList()));
				messageMapper.update(null, updateWrapper);
			}
		}
		return historyMessage;
	}

	@Override
	public void haveReadMessage(Long messageId) {
		LambdaUpdateWrapper<Message> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.set(Message::getReadStatus, MessageReadStatus.HAVE_READ.getStatus()).eq(Message::getId, messageId);
		messageMapper.update(null, updateWrapper);
	}
}
